package com.lenovo.leos.letools.lenovodata;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.text.DecimalFormat;

import javax.net.ssl.HttpsURLConnection;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.lenovo.leos.letools.db.FileDownloadEntity;
import com.lenovo.leos.letools.db.FileDownloadService;
import com.lenovo.leos.letools.exception.NetException;
import com.lenovo.leos.letools.interaces.DownloadProgressListener;
import com.lenovo.leos.letools.net.HttpGet;
import com.lenovo.leos.letools.net.ResponseValue;
import com.lenovo.leos.letools.utils.Constants;
import com.lenovo.leos.letools.utils.CookieStore;
import com.lenovo.leos.letools.utils.MyX509TrustManager;
import com.lenovo.leos.letools.utils.StreamTool;

public class DownLoadThread extends Thread {

	private String fileId;// 要下载文件id
	//the fileLength is can be the length of file or dir
	private int fileLength;
	private Context context;
	private String cookie_auth;
	private String cookie_token;
	private DownloadProgressListener downloadProgressListener;// 下载进展监听类
	private FileDownloadService fileService;
	private boolean _flag_pause = false;// 是否暂停下载
	private DownLoadServer.TotalFilelenPreDir tfld = null;// DownLoadServer的内部类 用于下载文件夹
	private String downloadURL;
	int totallen=0;	
    private int number = 2;

	/**
	 * 用于下载一般文件
	 * @param context
	 * @param fileId
	 */
	public DownLoadThread(Context context, String fileId,int length) {
		this.fileId = fileId;
		this.context = context;
		this.fileLength = length;
		fileService = new FileDownloadService(context);
	}
	/**
	 * 用于下载文件夹
	 * @param context
	 * @param fileId
	 * @param tfld
	 */
	public DownLoadThread(Context context, String fileId,DownLoadServer.TotalFilelenPreDir tfld,int fileLen) {
		this.fileId = fileId;
		this.context = context;
		this.tfld = tfld;
		this.fileLength = fileLen;
		fileService = new FileDownloadService(context);
	}
	
	public void setTotalFilelenPreDir(DownLoadServer.TotalFilelenPreDir tfld){
		this.tfld = tfld;
	}

	@Override
	public void run(){
		predownload();
		download();
	}
	/**
	 * 预下载文件
	 * 
	 * @param context
	 * @param fileid
	 * @return
	 * @throws NetException 
	 */
	public void predownload(){
		if(fileId==null) fileId="";
		String urlpath = Constants.LENOVODATA_FILE_PRODOWNLOAD + fileId.trim();
		cookie_auth = CookieStore.getCookie(context);// auth
		HttpGet get = new HttpGet(urlpath, cookie_auth);
		ResponseValue resVal = null;
		try {
			resVal = get.doGet();
		} catch (NetException e) {
			if(downloadProgressListener!=null)
				downloadProgressListener.onDownloadException(e.getId());//输出错误编号
			e.printStackTrace();
		}
		// 从返回的cookie信息集合去出TOKEN和FILENAME信息
		for (String cookieVal : resVal.getCookies()) {
			if (cookieVal.contains("TOKEN")) {
				cookie_token = cookieVal;
			}
		}
		// 返回请求的数据,这个值就是下载操作函数用到的URL(就是Constants.LENOVODATA_FILE_DOWNLOAD)
		// String downloadURL = StreamTool.parseStream(resVal.getInputStream());
		downloadURL = StreamTool.parseStream(resVal.getInputStream());
		get.closeConn();
	}

	/**
	 * 下载
	 * @throws Exception 
	 */
	public void download(){
//		String urlpath = Constants.LENOVODATA_FILE_DOWNLOAD + fileId;
		String urlpath = downloadURL +"/file/download/" + fileId;
		
		// 获取每条线程已经下载的文件长度
		int alreadyDownloadFileLen = fileService.getData(fileId);
		// 设置当前从什么位置下载这个文件
		int startposition = alreadyDownloadFileLen;
		
		//下文件夹用到
		if(tfld!=null){
			tfld.mulFileTotalLen+=startposition;
		}
		//设置当前下载任务  为正在下载
		fileService.updateIsLoading(fileId,FileDownloadService.isloading_yes);
		
		StringBuffer cookie = new StringBuffer();
		cookie.append(cookie_auth).append(";").append(cookie_token);

		MyX509TrustManager.allowAllSSL();
		HttpsURLConnection conn = null;
		InputStream in = null;
		try {
			conn = (HttpsURLConnection) (new URL(urlpath)).openConnection();
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Cookie", cookie.toString());
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn
					.setRequestProperty(
							"Accept",
							"image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
			conn.setRequestProperty("Accept-Language", "zh-CN");
			conn.setRequestProperty("Referer", urlpath.toString());
			conn.setRequestProperty("Charset", "UTF-8");
			/**
			 * 当bytes的值超过文件的最大长度的值时  ，会在执行到
			 * conn.getInputStream（）方法是  抛出 FileNotFoundException的异常
			 */
			conn.setRequestProperty("Range", "bytes=" + startposition + "-");
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.connect();
			in = conn.getInputStream();

			FileDownloadEntity entity = fileService.getFileDownloadEntity(fileId);
			String fileWholePath = entity.getFileWholePath();
			String newName = getFileName(fileWholePath);
			Log.d("filepath", "the newName is ================ " + newName);
			File file = new File(fileWholePath);
			if(null != newName){
				File newFile = new File(newName);
				file.renameTo(newFile);
			}
			// 通过这个流 可以在文件的不同部分操作文件。rw表示文件可以读写  d表示立即写入文件不缓存
			RandomAccessFile rdm = new RandomAccessFile(file, "rwd");
			rdm.seek(startposition);

			int len = -1;
			byte[] buffer = new byte[1024];
			DecimalFormat df = new DecimalFormat("###");   
			while ((len = in.read(buffer)) != -1 && _flag_pause == false) {
				rdm.write(buffer, 0, len);
				startposition += len;
				// 实时更新进度条
//				if(downloadProgressListener!=null){
//					downloadProgressListener.onDownloadSize(startposition);
//					double percent = (double)startposition/(double)fileLength * 100;
//					String value = df.format(percent) + "%";
//					String down_and_all = " " +  transferSize(startposition) + "/" + transferSize(fileLength);
//					downloadProgressListener.onChangeDownText(value + down_and_all);
//				}
				
				//add by gaoge 2011-04-25 
				double percent = (double)startposition/(double)fileLength * 100;
				String value = df.format(percent) + "%";
				String down_and_all = " " +  transferSize(startposition) + "/" + transferSize(fileLength);
				
				refreshUI(value + down_and_all, startposition);
				
				// 实时更新当前任务下载了多少字节的数据了
				fileService.update(fileId, startposition);
				
				
				//下文件夹用到
				if(tfld!=null){
//					tfld.mulFileTotalLen+=len;
//					tfld.downloadProgressListener.onDownloadSize(tfld.mulFileTotalLen);
//					//add by gaoge for show percent of download dir
//					double percent_dir= (double)tfld.mulFileTotalLen/(double)fileLength * 100;
//					String value_dir = df.format(percent_dir) + "%";
//					String down_and_all_dir = " " +  transferSize(tfld.mulFileTotalLen) + "/" + transferSize(fileLength);
//					tfld.downloadProgressListener.onChangeDownText(value_dir + down_and_all_dir);
					
					tfld.mulFileTotalLen+=len;
					//add by gaoge for show percent of download dir
					double percent_dir= (double)tfld.mulFileTotalLen/(double)fileLength * 100;
					String value_dir = df.format(percent_dir) + "%";
					String down_and_all_dir = " " +  transferSize(tfld.mulFileTotalLen) + "/" + transferSize(fileLength);
					for(int i=0;i<3;i++){
						Log.d("DownLoadThread","################ percent is: ");
					}
					refreshDirUI(value_dir + down_and_all_dir, tfld.mulFileTotalLen,tfld.getDirPercent(),tfld.getDirProgressBar());
				}
				
				
				Log.i("download","========="+Thread.currentThread().getName()+" is downloading========"+startposition+"---"+_flag_pause+"--len---"+len);
			}
			rdm.close();
			in.close();
			
			// 下载完成后，设置这个下载任务的状态为 “完成”
			if(entity.getFilelen() == startposition){
				Log.i("end","========="+Thread.currentThread().getName()+" is ended!!========");
				if(downloadProgressListener!=null)
					downloadProgressListener.onDownloadOver(fileId);
				fileService.updateIsOver(fileId, FileDownloadService.loadover_yes);
			}else{
				Log.i("pause","========="+Thread.currentThread().getName()+" is pause!!========"+"---"+_flag_pause);
				if(downloadProgressListener!=null)
					downloadProgressListener.onDownloadPause(fileId);
			}

		} catch (Exception e) {
			if(downloadProgressListener!=null){
				downloadProgressListener.onDownloadException(1);
			e.printStackTrace();
			}
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
			//设置当前下载任务  为没有正在下载
			fileService.updateIsLoading(fileId,FileDownloadService.isloading_no);
		}
	}

        private String getFileName(String fileWholePath) {
		int dex = fileWholePath.lastIndexOf("/");
		String path = fileWholePath.substring(0, dex);
		String fileName = fileWholePath.substring(dex + 1,
				fileWholePath.length());
		String newWholePath = null;
		Log.d("filepath", "path===================" + path);
		Log.d("filepath", "fileName===================" + fileName);
		String first, last;
		int number = 0;
		File file = new File(path);
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			if (files.length == 1) {
				return fileWholePath;
			} else {
				for (int i = 0; i < files.length; i++) {
					Log.d("filepath", "newfileName=================== " + i
							+ "=======" + files.length + "====fileName="
							+ fileName + "====isFile="
							+ files[i].getName().equals(fileName));
					if (files[i].getName().equals(fileName)
							&& files[i].isFile()) {
						number = i + 1;
						Log.d("filepath", "newfileName---------------- " + i);
						int index = files[i].getName().indexOf(".");
						first = files[i].getName().substring(0, index);
						last = files[i].getName().substring(index,
								files[i].getName().length());
						fileName = first + "(" + number++ + ")" + last;
						Log.d("filepath", "newfileName==================="
								+ fileName);
						newWholePath = path + "/" + fileName;
						break;
					} else {
						continue;
					}
				}
			}
		}
		return newWholePath;
	}

	public void setDownloadProgressListener(
			DownloadProgressListener downloadProgressListener) {
		this.downloadProgressListener = downloadProgressListener;
	}

	public void set_flag_pause(boolean flagPause) {
		_flag_pause = flagPause;
	}
	
	 public static  String transferSize(long lSize) {
         String size;
         int iPoint;
         if (lSize < 1024) {
                 size = lSize + "B";
         } else if (lSize < 1024 * 1024) {
                 size = String.valueOf(lSize / 1024.0);
                 iPoint = size.indexOf(".");
                 size = size.substring(0, iPoint + 2) + "K";
         } else if (lSize < 1024 * 1024 * 1024) {
                 size = String.valueOf(lSize / 1024.0 / 1024);
                 iPoint = size.indexOf(".");
                 size = size.substring(0, iPoint + 2) + "M";
         } else if (lSize < 1024L * 1024L * 1024L * 1024L) {
                 // Log.d(TAG, "%%%%%%%%%%%%%%%%%%%%%%%%%lSize_G="+lSize);
                 size = String.valueOf(lSize / 1024.0 / 1024 / 1024);
                 iPoint = size.indexOf(".");
                 size = size.substring(0, iPoint + 2) + "G";
         } else if (lSize < 1024L * 1024L * 1024L * 1024L * 1024L) {
                 // Log.d(TAG, "%%%%%%%%%%%%%%%%%%%%%%%%%lSize_T="+lSize);
                 size = String.valueOf(lSize / 1024.0 / 1024 / 1024 / 1024);
                 iPoint = size.indexOf(".");
                 size = size.substring(0, iPoint + 2) + "T";
         } else {
                 // Log.d(TAG, "%%%%%%%%%%%%%%%%%%%%%%%%%lSize_Unknown="+lSize);
                 size = "unknown";
         }


         return size;
 }
	 	public void setTv_percent(TextView tvPercent) {
			this.tv_percent = tvPercent;
		}

		public void setmProgressBar(ProgressBar mProgressBar) {
			this.mProgressBar = mProgressBar;
		}

		
	 Message msg;
	 private void refreshUI(String tv_percent_val,int progrossBarSize){
		 //这里需要判断mProgressBar是否为空，因为对于下载文件夹的时候，对于该文件夹下的每个文件，都会开启线程，
		 //对于这些线程来说，他们是没有progressBar的，他们这些线程只共有一个progressBar,就是TotalFilelenPreDir
		 //中的progressBar
		 if(null != mProgressBar){
			 mProgressBar.setProgress(progrossBarSize);
			 msg = mHandler.obtainMessage(CHANGE_PERCENT, tv_percent_val);
			 mHandler.sendMessage(msg);
		 }
	 }
	 private TextView tv_tmp_dir;
	 
	 private void refreshDirUI(String tv_percent_val_dir,int progrossBarSize,TextView tv_dir,ProgressBar bar_dir ){
		 tv_tmp_dir = tv_dir;
		 bar_dir.setProgress(progrossBarSize);
		 msg = mHandler.obtainMessage(CHANGE_PERCENT_DIR, tv_percent_val_dir);
		 mHandler.sendMessage(msg);
	 }
	 
	//add by gaoge 2011-04-25 
	private TextView tv_percent;
	private ProgressBar mProgressBar;
	private TextView 
		
	 public static final int CHANGE_PERCENT = 1;
	 public static final int CHANGE_PERCENT_DIR = 2;
	 
	 private Handler mHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if(CHANGE_PERCENT == msg.what){
				if(null != tv_percent){
					tv_percent.setText((String)msg.obj);
				}
			}
			else if(CHANGE_PERCENT_DIR == msg.what){
				tv_tmp_dir.setText((String)msg.obj);
			}
		}
	 };
}
